package com.dyzx.hbb.modules.finance.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.dyzx.hbb.common.base.Result;
import com.dyzx.hbb.common.config.MyLambdaQueryWrapper;
import com.dyzx.hbb.common.controller.BaseCustomController;
import com.dyzx.hbb.common.controller.BaseValidController;
import com.dyzx.hbb.common.utils.Utils;
import com.dyzx.hbb.modules.finance.entity.FinanceCategory;
import com.dyzx.hbb.modules.finance.entity.FinanceOrganApproval;
import com.dyzx.hbb.modules.finance.entity.FinanceOrganWallet;
import com.dyzx.hbb.modules.finance.entity.FinanceOrganWalletBill;
import com.dyzx.hbb.modules.finance.query.FinanceOrganWalletBillQuery;
import com.dyzx.hbb.modules.finance.service.FinanceOrganWalletBillService;
import com.dyzx.hbb.modules.finance.service.FinanceOrganWalletService;
import com.dyzx.hbb.modules.finance.vo.FinanceOrganWalletBillUVO;
import com.dyzx.hbb.modules.finance.vo.FinanceOrganWalletBillVO;
import com.dyzx.hbb.security.context.SecurityContextHolder;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 机构钱包流水控制器
 * <p>处理财务系统中机构钱包的流水记录管理，包括流水查询、统计和新增等功能
 * <p>主要职责：
 * <ul>
 * <li>提供机构钱包流水的基础CRUD接口</li>
 * <li>实现流水记录的条件查询和详情查询</li>
 * <li>提供首页展示的简易流水列表</li>
 * <li>支持收支统计功能（包括本月与上月对比）</li>
 * <li>处理资金流入记录的创建</li>
 * </ul>
 * <p>设计意图：为财务管理模块提供完整的资金流水管理功能，
 * 确保机构资金变动的可追溯性和透明度
 * 
 * @author 开发团队
 * @version 1.0.0
 * @since 2023-05-30
 */
@RestController
@RequestMapping("/finance/organ_bill")
@Tag(name = "07.财务-机构钱包流水")
public class FinanceOrganWalletBillController extends BaseCustomController<FinanceOrganWalletBillService, FinanceOrganWalletBill, FinanceOrganWalletBillQuery> {

  @Autowired
  private FinanceOrganWalletBillService service;
  @Autowired
  private FinanceOrganWalletService organWalletService;
/*    @Override
    protected FinanceOrganWalletBill addValid(FinanceOrganWalletBillVO entity) {
        FinanceOrganWalletBill data = new FinanceOrganWalletBill();
        BeanUtil.copyProperties(entity, data);
        String no = Utils.generateYyMMOrderNumber("FB");
        data.setNo(no);
        return  data;
    }

    @Override
    protected FinanceOrganWalletBill editValid(FinanceOrganWalletBillUVO entity) {
        return null;
    }*/

    @Override
    protected FinanceOrganWalletBillService getBaseService() {
        return service;
    }

    @Override
    protected MyLambdaQueryWrapper<FinanceOrganWalletBill> queryWrapper(FinanceOrganWalletBillQuery query) {
        MyLambdaQueryWrapper<FinanceOrganWalletBill> queryWrapper = new MyLambdaQueryWrapper<>();
        queryWrapper.select(FinanceOrganWalletBill::getId)
                .select(FinanceOrganWalletBill::getNo)
               .select(FinanceOrganWalletBill::getApprovalId)
               // .select(FinanceOrganWalletBill::getSalesmanId)
                .select(FinanceOrganWalletBill::getAmount)
                .select(FinanceOrganWalletBill::getState)
                .userName(FinanceOrganWalletBill::getApprovalId).as("approval_name")
                .userName(FinanceOrganWalletBill::getSalesmanId).as("salesman_name")
                .select("(SELECT name FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("name")
                .select("(SELECT color FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("color")
                .select("(SELECT icon FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("icon");
              //  .select(FinanceOrganWalletBill::getCategoryId);

        if(query!=null){
            if(query.getPaid()==null){
                queryWrapper.eq(FinanceOrganWalletBill::getIsPaid, 2);
            }else{
                queryWrapper.eq(FinanceOrganWalletBill::getIsPaid, query.getPaid());
            }
            queryWrapper.eq(FinanceOrganWalletBill::getOrganId, SecurityContextHolder.getOrganId());
            queryWrapper.eq(query.getState()!=null,FinanceOrganWalletBill::getState, query.getState());
        }else{
            queryWrapper.eq(FinanceOrganWalletBill::getIsPaid, 2);
        }

        return queryWrapper;
    }

    @Override
    protected MyLambdaQueryWrapper<FinanceOrganWalletBill> queryInfoWrapper() {
        MyLambdaQueryWrapper<FinanceOrganWalletBill> queryWrapper = new MyLambdaQueryWrapper<>();
        queryWrapper.select(FinanceOrganWalletBill::getId)
                .select(FinanceOrganWalletBill::getNo)
                .select(FinanceOrganWalletBill::getWalletId)
                .select(FinanceOrganWalletBill::getSalesmanId)
                .select(FinanceOrganWalletBill::getAmount)
                .select(FinanceOrganWalletBill::getState)
                .select(FinanceOrganWalletBill::getCategoryId)
                .select(FinanceOrganWalletBill::getRemark)
                .select(FinanceOrganWalletBill::getImageId)
                .select(FinanceOrganWalletBill::getCreateDate)
                .select(FinanceOrganWalletBill::getUpdateDate)
                .select(FinanceOrganWalletBill::getApprovalId)
                // .select(FinanceOrganWalletBill::getWalletId)
                // .select(FinanceOrganWalletBill::getSalesmanId)
                .userName(FinanceOrganWalletBill::getSalesmanId).as("salesman_name")

                .select("(SELECT name FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("name")
                .select("(SELECT color FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("color")
                .select("(SELECT icon FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("icon")

                .imageUrl(FinanceOrganWalletBill::getImageId).as("image_url");
        return queryWrapper;
    }


    @Operation(summary = "简易列表")
    @GetMapping("/home_list")
    public Result<List<Map<String, Object>>> homeList(
    ) {
        Long organId = SecurityContextHolder.getOrganId();
        MyLambdaQueryWrapper<FinanceOrganWalletBill> wrapper =queryWrapper( null);
        wrapper.select(FinanceOrganWalletBill::getId, FinanceOrganWalletBill::getStatus)
                .select(FinanceOrganWalletBill::getAmount)
               // .userName(FinanceOrganWalletBill::getSalesmanId).as("salesman_name")
                .organName(FinanceOrganWalletBill::getOrganId).as("organ_name")
                .userName(FinanceOrganWalletBill::getOperatorId).as("operator_name")
                .select(FinanceOrganWalletBill::getState, FinanceOrganWalletBill::getCreateDate, FinanceOrganWalletBill::getUpdateDate)
                .select("(SELECT name FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("name")
                .select("(SELECT color FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("color")
                .select("(SELECT icon FROM finance_category WHERE id = finance_organ_wallet_bill.category_id)").as("icon");
        wrapper.orderByDesc(FinanceOrganWalletBill::getId);
        wrapper.eq(FinanceOrganWalletBill::getIsPaid, 2).eq(FinanceOrganWalletBill::getOrganId, SecurityContextHolder.getOrganId());

        wrapper.last("limit 5");

        List<Map<String, Object>> list = getBaseService().listMaps(wrapper);
        return list.isEmpty() ? Result.error(404, "暂无数据") : Result.ok(list);
    }

    //
    @GetMapping("/total")
    public Result<Map<String, Object>> total(
    ) {
        FinanceOrganWallet blance =organWalletService.getByOrganId(SecurityContextHolder.getOrganId());;
       Map<String, Object> map = new HashMap<>();
       map.put("in", total(1));
       map.put("out", total(2));
       map.put("balance", blance.getBalance());

       return Result.ok(map);


    }
    private  Map<String, Object> total(int state) {
        Long organId = SecurityContextHolder.getOrganId();
        MyLambdaQueryWrapper<FinanceOrganWalletBill> wrapper = new MyLambdaQueryWrapper<>();
        wrapper.eq(FinanceOrganWalletBill::getOrganId, organId);
        wrapper.eq(FinanceOrganWalletBill::getState, state).eq(FinanceOrganWalletBill::getIsPaid, 2);
        wrapper.sum(FinanceOrganWalletBill::getAmount).as("amount");
        wrapper.groupBy(FinanceOrganWalletBill::getState);
        wrapper.apply("DATE_FORMAT(FROM_UNIXTIME(create_date/1000),'%Y-%m') = DATE_FORMAT(NOW(),'%Y-%m')");

        // 获取上月数据
        String lastMonth = DateUtil.format(DateUtil.lastMonth(), "yyyy-MM");
        MyLambdaQueryWrapper<FinanceOrganWalletBill> lastMonthWrapper = new MyLambdaQueryWrapper<>();
        lastMonthWrapper.eq(FinanceOrganWalletBill::getOrganId, organId);
        lastMonthWrapper.eq(FinanceOrganWalletBill::getState, state).eq(FinanceOrganWalletBill::getIsPaid, 2);
        lastMonthWrapper.sum(FinanceOrganWalletBill::getAmount).as("last_month_amount");
        lastMonthWrapper.groupBy(FinanceOrganWalletBill::getState);
        lastMonthWrapper.apply("DATE_FORMAT(FROM_UNIXTIME(create_date/1000),'%Y-%m') = '"+lastMonth+"'");

        Map<String, Object> currentMonth = service.getMap(wrapper);
        Map<String, Object> lastMonthData = service.getMap(lastMonthWrapper);
        if(currentMonth == null) {
            currentMonth = new HashMap<>();
            currentMonth.put("amount", 0);
        }

        // 计算差异和百分比
        if(currentMonth != null && lastMonthData != null) {
            double current = Double.parseDouble(currentMonth.get("amount").toString());
            double last = Double.parseDouble(lastMonthData.get("last_month_amount").toString());
            double diff = current - last;
            double percentage = (diff / last) * 100;

            currentMonth.put("difference", diff);
            currentMonth.put("percentage", percentage>100?100:percentage);
        }else {
            currentMonth.put("difference", 0);
            currentMonth.put("percentage", 0);
        }

        return currentMonth;
    }

    @PostMapping
    public Result<Boolean> save(@Valid @RequestBody FinanceOrganWalletBillVO param) {
        Long userId = SecurityContextHolder.getUserId();
        Long organId = SecurityContextHolder.getOrganId();
        FinanceOrganWalletBill data = new FinanceOrganWalletBill();
        BeanUtil.copyProperties(param, data);
        String no = Utils.generateYyMMOrderNumber("FB");
        data.setNo(no);
        data.setOperatorId(userId);
        data.setOrganId(organId);
        data.setSalesmanId(userId);
        boolean save =service.walletBillIn(data);
        return save ? Result.ok() : Result.error(500, "保存失败");
    }
}
